package me.lc.superDown.core;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CopyOnWriteArrayList;

import me.lc.superDown.layer.GameLayer;
import me.lc.superDown.sprite.GameTool;
import me.lc.superDown.sprite.Platform;
import me.lc.superDown.sprite.RunGuy;
import me.lc.superDown.sprite.platforms.BreakPlatform;
import me.lc.superDown.sprite.platforms.MiniPlatform;
import me.lc.superDown.sprite.platforms.NormalPlatform;
import me.lc.superDown.sprite.platforms.SpeedDownPlatform;
import me.lc.superDown.sprite.tools.CoinTool;
import me.lc.superDown.sprite.tools.FlowerTool;
import me.lc.superDown.sprite.tools.SpeedDownTool;
import me.lc.superDown.sprite.tools.SpeedUpTool;
import me.lc.superDown.util.AudioHelper;

import com.wiyun.engine.nodes.Scheduler;
import com.wiyun.engine.nodes.Timer;
import com.wiyun.engine.utils.ResolutionIndependent;
import com.wiyun.engine.utils.TargetSelector;

public class GameMap {
	public static GameMap instance = new GameMap();
	public static final float RunSpeed = ResolutionIndependent.resolveDp(12);
	public static final float MaxMoveUnit = ResolutionIndependent.resolveDp(7);

	CopyOnWriteArrayList<Platform> platformList;
	Object platformListSyncObj = new Object();

	float platformHeight = GameSystem.tex_platformNormal.getHeight();
	float manHeight = GameSystem.tex_manFaceLeft.getHeight();

	Platform currentStandPlatform = null;
	public RunGuy runGuy;
	float manX = 0, manY = 0;

	static float downSpeed = 15.9f;

	// 空中移动系数
	float jumpNum = 0;
	// 空中移动系数计算系数（除）
	static float jumpNumMulBase = 2.1f;
	// 下一个平台出现的间隔
	int nextPlatformInterval = 30;

	long lastTimeInterval = 35;
	/**
	 * 掉落速度
	 */
	float fallSpeed = ResolutionIndependent.resolveDp(3.0f);

	Random r = new Random((new Date()).getTime());

	boolean isOnPlatform = true;

	public void setOnPlatform(boolean isOnPlatform) {
		this.isOnPlatform = isOnPlatform;
	}

	/**
	 * 游戏是否正事开始
	 */
	boolean isStartGame = false;

	/**
	 * 是否是刚刚开始,控制刚开始的平台类型
	 */
	boolean isInitStarted = true;

	// Object timerSyncObj = new Object();

	Timer downTimer;
	Timer platformMoveTimer;
	TargetSelector tsDown;
	TargetSelector tsPMove;
	// Timer checkStatusTimer;

	GameLayer gameLayer;

	private GameMap() {
		platformList = new CopyOnWriteArrayList<Platform>();
		tsDown = new TargetSelector(this, "downTimerTask(float)",
				new Object[] { 0f });
		tsPMove = new TargetSelector(this, "platformMovingTask(float)",
				new Object[] { 0f });
	}

	public void initMainMenu(GameLayer gameLayer) {
		this.gameLayer = gameLayer;
		lastTimeInterval = 25;
		// 尝试释放runguy资源
		if (runGuy != null) {
			runGuy.autoRelease(true);
			runGuy = null;
		}
		if (platformMoveTimer != null) {
			Scheduler.getInstance().unschedule(platformMoveTimer);
			platformMoveTimer = null;
		}
		if (downTimer != null) {
			Scheduler.getInstance().unschedule(downTimer);
			downTimer = null;
		}
		synchronized (platformListSyncObj) {
			for (Platform platform : platformList) {
				platform.autoRelease(true);
			}
			platformList.clear();
		}

		this.gameLayer.btn_pause.setVisible(true);
		currentStandPlatform = null;
		gameLayer.removeAllChildren(true);
		isStartGame = false;
		isInitStarted = false;
		platformMoveTimer = new Timer(tsPMove, lastTimeInterval / 1000.0f);
		// platformMoveTimer.schedule(new PlatformMovingTask(), 100,
		// lastTimeInterval);
		Scheduler.getInstance().schedule(platformMoveTimer);
	}

	public void initNewGameMap(GameLayer gameLayer) {
		lastTimeInterval = 25;
		this.gameLayer = gameLayer;

		// 尝试释放runguy资源
		if (runGuy != null) {
			runGuy.autoRelease(true);
			runGuy = null;
		}
		if (platformMoveTimer != null) {
			Scheduler.getInstance().unschedule(platformMoveTimer);
			platformMoveTimer = null;
		}
		if (downTimer != null) {
			Scheduler.getInstance().unschedule(downTimer);
			downTimer = null;
		}
		isOnPlatform = true;
		jumpNum = 0;
		nextPlatformInterval = 40;
		synchronized (platformListSyncObj) {
			for (Platform platform : platformList) {
				platform.autoRelease(true);
			}
			platformList.clear();
		}
		currentStandPlatform = null;
		isInitStarted = true;
		gameLayer.removeAllChildren(true);
		GameSystem.PlatformMoveUnit = ResolutionIndependent.resolveDp(3);

		this.gameLayer.btn_pause.setVisible(true);
		// 增加时钟显示
		this.gameLayer.addChild(this.gameLayer.clockBar, 4);
		this.gameLayer.addChild(this.gameLayer.coinBar, 4);
		this.gameLayer.addChild(this.gameLayer.btn_pause, 4);

		setStandPlatform(gameLayer);

		runGuy = new RunGuy();
		setRunGuyPostion(GameSystem.Screen_Width / 2,
				GameSystem.Screen_Height / 2 + platformHeight / 2
						+ GameSystem.tex_manFaceRight.getHeight() / 2);
		gameLayer.addChild(runGuy, 2);

		// 初始化人物位置
		manX = GameSystem.Screen_Width / 2;
		manY = GameSystem.Screen_Height / 2 + platformHeight / 2
				+ GameSystem.tex_manFaceRight.getHeight() / 2;

		isStartGame = true;

		downTimer = new Timer(tsDown, downSpeed / 1000.0f);
		Scheduler.getInstance().schedule(downTimer);
		// downTimer.schedule(new DownTimerTask(), 20, 20);

		platformMoveTimer = new Timer(tsPMove, lastTimeInterval / 1000.0f);
		// platformMoveTimer.schedule(new PlatformMovingTask(), 100,
		// lastTimeInterval);
		Scheduler.getInstance().schedule(platformMoveTimer);
	}

	private void setStandPlatform(GameLayer gameLayer) {
		Platform platform = new NormalPlatform();
		platform.setPosition(GameSystem.Screen_Width / 2,
				GameSystem.Screen_Height / 2);
		gameLayer.addChild(platform);
		platform.setLocationInfo(GameSystem.Screen_Width / 2,
				GameSystem.Screen_Height / 2);
		synchronized (platformListSyncObj) {
			platformList.add(platform);
		}
		currentStandPlatform = platform;

		Platform platform2 = new NormalPlatform();
		platform2.setPosition(
				GameSystem.Screen_Width / 2 - platform2.getPlatformWidth() / 2,
				GameSystem.Screen_Height / 4);
		gameLayer.addChild(platform2);
		platform2.setLocationInfo(
				GameSystem.Screen_Width / 2 - platform2.getPlatformWidth() / 2,
				GameSystem.Screen_Height / 4);
		synchronized (platformListSyncObj) {
			platformList.add(platform2);
		}

		Platform platform3 = new NormalPlatform();
		platform3.setPosition(
				GameSystem.Screen_Width / 2 + platform2.getPlatformWidth() / 2,
				0);
		gameLayer.addChild(platform3);

		platform3.setLocationInfo(
				GameSystem.Screen_Width / 2 + platform2.getPlatformWidth() / 2,
				0);
		synchronized (platformListSyncObj) {
			platformList.add(platform3);
		}
	}

	/**
	 * 设置微量移动系数
	 * 
	 * @param x
	 */
	public void setJumpNum(float x) {
		// 设置移动系数
		jumpNum = x / jumpNumMulBase;
	}

	public synchronized void moveMan(float x) {
		if (isStartGame && isOnPlatform) {
			x = x * GameManager.instance.speedBonus
					* GameManager.instance.toolSpeedBonus;
			float aimX = manX + x;
			if (aimX < 0) {
				aimX = GameSystem.Screen_Width;
			} else if (aimX > GameSystem.Screen_Width) {
				aimX = 0;
			}
			manX = aimX;
			setRunGuyPostion(aimX, manY);
			if (x > 0) {
				runGuy.runRight();
			} else if (x < 0) {
				runGuy.runLeft();
			}

			// 判断是否超出了
			if (currentStandPlatform != null) {
				if (currentStandPlatform.location.getStartX() - manHeight / 56 > manX
						|| currentStandPlatform.location.getEndX() + manHeight
								/ 56 < manX) {

					isOnPlatform = false;

					// 设置平台属性
					currentStandPlatform.setCanStand(false);
					currentStandPlatform.leavePlatform();
					currentStandPlatform = null;

				}
			} else {
				isOnPlatform = false;
			}

			checkHitTool();
		} else {
			// 设置移动系数
			jumpNum = x / jumpNumMulBase;
			standGuy();
		}
	}

	boolean isHitting;

	/**
	 * 检查道具碰撞
	 */
	private void checkHitTool() {
		if (isHitting) {
			return;
		}
		isHitting = true;
		if (isOnPlatform && currentStandPlatform != null && runGuy != null
				&& currentStandPlatform.getTool() != null
				&& !currentStandPlatform.getTool().isHited) {
			GameTool tool = currentStandPlatform.getTool();
			float toolStartX = tool.getPositionX() - tool.getToolWidth() / 2;
			float toolEndX = tool.getPositionX() + tool.getToolWidth() / 2;
			float runGuyStartX, runGuyEndX;
			runGuyStartX = manX - runGuy.getManWidth() / 2;
			runGuyEndX = manX + runGuy.getManWidth() / 2;
			if (toolStartX <= runGuyEndX && toolStartX >= runGuyStartX
					|| runGuyStartX <= toolEndX && runGuyStartX >= toolStartX) {
				tool.hitTool();
			}
		}
		isHitting = false;
	}

	public void standGuy() {
		if (isStartGame) {
			runGuy.stop();
		}
	}

	/**
	 * 检查游戏是否结束
	 * 
	 * @return true 结束
	 */
	public synchronized boolean checkGameFinished() {
		// 任务的Y坐标是否大于屏幕高度或者小于0则游戏结束
		if (isStartGame) {
			if (manY > GameSystem.Screen_Height + manHeight / 2 || manY < 0) {
				isStartGame = false;
				// 游戏结束
				runGuy.setVisible(false);
				GameManager.instance.finishGame();
				gameLayer.btn_pause.setVisible(false);
				if (downTimer != null) {
					Scheduler.getInstance().unschedule(downTimer);
					downTimer = null;
				}
				return true;
			}
			return false;
		}
		return false;
	}

	public void downTimerTask(float value) {
		// System.out.println("DownTimerTask");
		if (isOnPlatform || GameManager.instance.isPaused) {
			return;
		}
		if (isStartGame) {
			float aimX = manX + jumpNum;
			if (aimX < 0) {
				aimX = GameSystem.Screen_Width;
			} else if (aimX > GameSystem.Screen_Width) {
				aimX = 0;
			}
			manX = aimX;
			manY = manY - fallSpeed;
			setRunGuyPostion(manX, manY);
			if (jumpNum >= 0) {
				runGuy.faceRight();
			} else {
				runGuy.faceLeft();
			}
		}

	}

	private int pCount = 0;

	public void platformMovingTask(float value) {
		// System.out.println("PlatformMovingTask");
		// synchronized (isDoingSyncObj) {
		// if (isDoing) {
		// System.out.println("PlatformMovingTask isDoing");
		// return;
		// }
		// isDoing = true;
		// }

		if (GameManager.instance.isPaused) {
			return;
		}
		synchronized (platformListSyncObj) {
			for (Platform platform : platformList) {
				// 向上移动平台
				platform.setPosition(platform.getPositionX(),
						platform.getPositionY() + GameSystem.PlatformMoveUnit);
				platform.location.setY(platform.location.getY()
						+ GameSystem.PlatformMoveUnit);

				if (platform.getTool() != null) {
					platform.getTool().setPosition(
							platform.getTool().getPositionX(),
							platform.getTool().getPositionY()
									+ GameSystem.PlatformMoveUnit);
				}
			}
		}
		if (isStartGame) {
			if (isOnPlatform) {
				// 向上移动
				manY = manY + GameSystem.PlatformMoveUnit;
				setRunGuyPostion(manX, manY);

			} else {
				// // 设置位置
				// float aimX = manX + jumpNum;
				// if (aimX < 0) {
				// aimX = GameSystem.Screen_Width;
				// } else if (aimX > GameSystem.Screen_Width) {
				// aimX = 0;
				// }
				// manX = aimX;
				// manY = manY - fallSpeed;
				// setRunGuyPostion(aimX, manY);
				// if (jumpNum >= 0) {
				// runGuy.faceRight();
				// } else {
				// runGuy.faceLeft();
				// }
			}
			if (checkGameFinished()) {
				if (platformMoveTimer != null) {
					Scheduler.getInstance().unschedule(platformMoveTimer);
					platformMoveTimer = null;
				}
				if (downTimer != null) {
					Scheduler.getInstance().unschedule(downTimer);
					downTimer = null;
				}
				// synchronized (isDoingSyncObj) {
				// isDoing = false;
				// }
				return;
			}
			// 检查能否落地
			checkStatus();
		}

		// 加入新的平台
		pCount++;
		if (pCount >= nextPlatformInterval) {
			pCount = 0;

			// 生成下一次生成平台的间隔数值
			genNextPlatformInterval();

			// 加入一个新的platform
			Platform newOne = genNewPlatform();
			float x = r.nextInt((int) (GameSystem.Screen_Width - newOne
					.getPlatformWidth())) + newOne.getPlatformWidth() / 2;
			float y = 0 - platformHeight / 2;
			newOne.setLocationInfo(x, y);
			newOne.setPosition(x, y);
			synchronized (platformListSyncObj) {
				platformList.add(newOne);
			}

			gameLayer.addChild(newOne, 1);

			// 增加道具
			GameTool newTool = genNewTool();
			if (newTool != null) {
				newOne.setTool(newTool);

				float toolXStart = x - newOne.getPlatformWidth() / 2
						+ newTool.getToolWidth() / 2;
				float tempWidth = newOne.getPlatformWidth()
						- newTool.getToolWidth();
				float toolX = r.nextInt((int) tempWidth) + toolXStart;

				newTool.setPosition(toolX, y + newTool.getToolHeight() / 2
						+ platformHeight / 2);

				gameLayer.addChild(newTool, 3);
			}

			// 回收平台
			List<Platform> deleteLst = new ArrayList<Platform>();
			synchronized (platformListSyncObj) {
				for (Platform platform : platformList) {
					if (platform.location.getY() > GameSystem.Screen_Height) {
						deleteLst.add(platform);
					}
				}
			}
			if (deleteLst.size() > 0) {
				for (Platform deleteP : deleteLst) {
					System.out.println("回收平台");
					synchronized (platformListSyncObj) {
						platformList.remove(deleteP);
					}
					gameLayer.removeChild(deleteP, true);
					if (deleteP.getTool() != null) {
						gameLayer.removeChild(deleteP.getTool(), true);
						deleteP.getTool().autoRelease(true);
					}
					deleteP.autoRelease(true);
				}
			}
		}
		// synchronized (isDoingSyncObj) {
		// isDoing = false;
		// }
	}

	private void checkStatus() {
		if (!isOnPlatform) {
			float tempManY = manY - manHeight / 2 - platformHeight / 2;
			// 遍历所有的平台，判断是否能够落地
			boolean isOnSth = false;
			Platform aimPlatform = null;
			synchronized (platformListSyncObj) {
				for (Platform platform : platformList) {
					if (!platform.isCanStand()) {
						continue;
					}

					if ((platform.location.getY() - platformHeight) <= tempManY
							&& (platform.location.getY() + platformHeight / 5) >= tempManY) {
						// 找到对应的平台, 判断X
						if (platform.location.getStartX() - manHeight / 56 <= manX
								&& platform.location.getEndX() + manHeight / 56 >= manX) {
							manY = platform.location.getY() + platformHeight
									/ 2 + manHeight / 2;
							setRunGuyPostion(manX, manY);

							isOnSth = true;
							aimPlatform = platform;
							break;
						}
					}
				}
			}

			// 重置跳跃参数
			if (isOnPlatform && !isOnSth) {
				jumpNum = 0;
			}
			if (isOnSth) {
				isOnPlatform = isOnSth;
				if (aimPlatform != null && !aimPlatform.isManLanded()) {
					AudioHelper.land();
					aimPlatform.setManLanded(true);
					currentStandPlatform = aimPlatform;
					aimPlatform.standPlatform();
					checkHitTool();
				}
			}
		}

	}

	/**
	 * 生成平台生成间隔
	 */
	private synchronized void genNextPlatformInterval() {
		// 20 15%, 30 20%, 40 30%, 50 30%, 58 5%
		int nextIntervalRand = r.nextInt(100);
		if (nextIntervalRand < 15) {
			nextPlatformInterval = 20;
		} else if (nextIntervalRand < 35) {
			nextPlatformInterval = 30;
		} else if (nextIntervalRand < 65) {
			nextPlatformInterval = 40;
		} else if (nextIntervalRand < 95) {
			nextPlatformInterval = 50;
		} else {
			nextPlatformInterval = 58;
		}
	}

	/**
	 * 创建一个新的平台
	 * 
	 * @return
	 */
	private synchronized Platform genNewPlatform() {
		if (isInitStarted) {
			return new NormalPlatform();
		}

		Platform platform = null;

		int tempRnd = r.nextInt(8);
		switch (tempRnd) {
		case 0:
		case 1:
		case 2:
			platform = new NormalPlatform();
			break;
		case 3:
		case 4:
			platform = new MiniPlatform();
			break;
		case 5:
			platform = new BreakPlatform();
			break;
		case 6:
		case 7:
			platform = new SpeedDownPlatform();
			break;
		}

		return platform;
	}

	/**
	 * 创建一个新道具
	 * 
	 * @return
	 */
	public synchronized GameTool genNewTool() {
		int tempRnd = r.nextInt(10);
		if (tempRnd >= 5) {
			// 需要生成道具
			GameTool tool = null;
			int temp = r.nextInt(15);
			switch (temp) {
			case 0:
			case 1:
				tool = new FlowerTool();
				break;
			case 2:
			case 3:
				tool = new SpeedDownTool();
				break;
			case 4:
			case 5:
				tool = new SpeedUpTool();
				break;
			default:
				tool = new CoinTool();
				break;
			}
			return tool;
		} else {
			return null;
		}
	}

	public synchronized void resetPlatformMoveInterval(long interval) {
		isInitStarted = false;
		if (platformMoveTimer != null) {
			Scheduler.getInstance().unschedule(platformMoveTimer);
			platformMoveTimer = null;
		}
		if (downTimer != null) {
			Scheduler.getInstance().unschedule(downTimer);
			downTimer = null;
		}

		// 需要修改 计算最新的掉落速度
		// fallSpeed = fallSpeed * (float) interval / (float) lastTimeInterval;
		// lastTimeInterval = (int) interval;

		// platformMoveTimer = new Timer();
		// platformMoveTimer.schedule(new PlatformMovingTask(), interval / 2,
		// interval);

		downTimer = new Timer(tsDown, downSpeed / 1000.0f);
		Scheduler.getInstance().schedule(downTimer);
		// downTimer.schedule(new DownTimerTask(), 20, 20);

		platformMoveTimer = new Timer(tsPMove, interval / 1000.0f);
		// platformMoveTimer.schedule(new PlatformMovingTask(), 100,
		// lastTimeInterval);
		Scheduler.getInstance().schedule(platformMoveTimer);
	}

	private synchronized void setRunGuyPostion(float x, float y) {
		runGuy.setPosition(x, y);
	}

}
